<?php

/**
 * ユーティリティクラス
 *
 * @package Apm
 * @author hiasa-ryousuke@systemsoft.co.jp
 * @since 2010/10/20
 */
class Apm_Util
{

    protected $_tmp = null;

    /**
     * データベースへSELECT文を送り、結果を返す<br>
     * 結果が1件の場合のみ、このメソッドを使用
     *
     * @param string $sql
     *            SQL文
     * @param array $db_params
     *            バインド変数
     * @return データベースの出力結果
     */
    public static function dbGetData($sql, $db_params = "", $db = "")
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        $param_db_connect = true;
        if (empty($db))
        {
            $db = self::getDbConnection();
            $param_db_connect = false;
        }
        if (empty($db_params))
        {
            $result = $db->query($sql);
        }
        else
        {
            $result = $db->query($sql, $db_params);
        }
        $data = $result->fetch();

        $profiler = $db->getProfiler();
        $profile_detail = array();
        self::getDbProfileDetail($profiler, $profile_detail);
        __log_debug(__FILE__, __LINE__, __METHOD__, 'クエリ実行所要時間 = ' . $profile_detail['elapsed_secs'] . ' / ' . 'フィールド取得件数 = ' . count($data));
        __log_debug(__FILE__, __LINE__, __METHOD__, 'バインドパラメータ = ' . $profile_detail['query_param']);
        __log_debug_ex('dbGetData --- クエリ実行所要時間 = ' . round((float) $profile_detail['elapsed_secs'], 5) . ' 秒 / ' . 'フィールド取得件数 = ' . count($data));
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        if ($param_db_connect == false)
        {
            $db->closeConnection();
        }
        return $data;
    }

    /**
     * データベースへSELECT文を送り、結果を返す<br>
     * 結果が複数件ある場合、このメソッドを使用
     *
     * @param string $sql
     *            SQL文
     * @param array $db_params
     *            バインド変数
     * @return データベースの出力結果
     */
    public static function dbGetList($sql, $db_params = "", $db = "")
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        if (empty($db))
        {
            $db = self::getDbConnection();
            $param_db_connect = false;
        }
        if (empty($db_params))
        {
            $result = $db->query($sql);
        }
        else
        {
            $result = $db->query($sql, $db_params);
        }
        $data = $result->fetchAll();

        $profiler = $db->getProfiler();
        $profile_detail = array();
        self::getDbProfileDetail($profiler, $profile_detail);
        __log_debug(__FILE__, __LINE__, __METHOD__, 'クエリ実行所要時間 = ' . $profile_detail['elapsed_secs'] . ' / ' . 'データ取得件数 = ' . count($data));
        __log_debug(__FILE__, __LINE__, __METHOD__, 'バインドパラメータ = ' . $profile_detail['query_param']);
        __log_debug_ex('dbGetList --- クエリ実行所要時間 = ' . round((float) $profile_detail['elapsed_secs'], 5) . ' 秒 / ' . 'フィールド取得件数 = ' . count($data));
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');

        if ($param_db_connect == false)
        {
            $db->closeConnection();
        }
        return $data;
    }

    /**
     * データベースへの接続を確立
     *
     * @return DBアダプター
     */
    public static function getDbConnection()
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        $configObject = Zend_Registry::get('config');
        $dbConfig = $configObject->database->toArray();
        $db_info = array();
        $db_info = array(
            'dbname' => $dbConfig['dbname'],
            'username' => $dbConfig['username'],
            'password' => $dbConfig['password'],
            'charset' => $dbConfig['charset'],
            'profiler' => $dbConfig['profiler'],
            'persistent' => $dbConfig['persistent']
        );
        $db = new Zend_Db_Adapter_Oracle($db_info);
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        return $db;
    }

    /**
     * データベースアクセス時のプロファイラを取得する<br>
     *
     * @param string $profiler
     *            プロファイラのインスタンス
     * @param
     *            array &$profile_detail
     *            プロファイラ情報の参照渡し
     * @return void
     */
    private static function getDbProfileDetail($profiler, &$profile_detail)
    {
        $last_query = $profiler->getLastQueryProfile();
        $profile_detail['query'] = $last_query->getQuery();
        $profile_detail['elapsed_secs'] = $last_query->getElapsedSecs();
        $tmp = $last_query->getQueryParams();
        if (!empty($tmp))
        {
            foreach ($tmp as $key => $value)
            {
                $profile_detail['query_param'] .= sprintf('[%s] => \'%s\', ', $key, $value);
            }
        }
        $profile_detail['query_param'] = rtrim($profile_detail['query_param'], ', ');
    }

    /**
     * ページャー生成に必要な情報を計算<br>
     * 引数で与えられた情報から、その他の情報を計算して返します<br>
     * 参考ページ ⇒ {@link http://dev-apamanshop/sample/shoplist ショップ一覧}
     *
     * @param integer $total_count
     *            全件数
     * @param integer $curpage
     *            現在のページ番号
     * @param integer $perpage
     *            1ページ中に表示する件数
     * @param integer $range
     *            ページャーの表示数
     * @return array
     */
    public static function generatePager($total_count, $curpage, $perpage, $range)
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        $total_count = ceil($total_count);
        // total_pages
        $total_pages = ceil($total_count / $perpage);

        // range
        $range = ($total_pages < $range) ? $total_pages : $range;

        // start_page
        $start_page = "1";
        if ($curpage >= ceil($range / 2))
        {
            $start_page = $curpage - floor($range / 2);
        }
        $start_page = ($start_page < 1) ? 1 : $start_page; // １未満は１にする

        // end_page
        $end_page = $start_page + $range - 1;
        if ($curpage > $total_pages - ceil($range / 2))
        { // 最後の方のページ等
            $end_page = $total_pages;
            $start_page = $end_page - $range + 1;
        }

        // start_cnt
        $start_cnt = ceil($curpage - 1) * $perpage + 1;

        // end_cnt
        $end_cnt = ceil($curpage) * $perpage < $total_count ? ceil($curpage) * $perpage : $total_count;

        // prev
        if ($curpage > $start_page)
        {
            $prev = $curpage - 1;
        }
        else
        {
            $prev = NULL;
        }

        // next
        if ($curpage < $end_page)
        {
            $next = $curpage + 1;
        }
        else
        {
            $next = NULL;
        }

        // offset
        $offset = ceil($curpage - 1) * $perpage;

        // limit
        $limit = ($total_count < $perpage) ? $total_count : $perpage;

        $paging_info = array();
        $paging_info = array(
            'total_count' => $total_count,
            'total_pages' => $total_pages,
            'curpage' => $curpage,
            'range' => $range,
            'start_page' => $start_page,
            'end_page' => $end_page,
            'start_cnt' => $start_cnt,
            'end_cnt' => $end_cnt,
            'prev' => $prev,
            'next' => $next,
            'offset' => $offset,
            'limit' => $limit
        );
        __log_debug_array(__FILE__, __LINE__, __METHOD__, $paging_info);
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        return $paging_info;
    }

    /**
     * htmlのhiddenタグを生成<br>
     * 引数で与えられた配列のキーと値を、hiddenタグのnameとvalueに埋め込みます<br>
     * 参考ページ ⇒ {@link http://dev-apamanshop/sample/inquiry/entry 問い合わせフォーム} (確認画面)
     *
     * @param array $params
     *            連想配列
     * @return string htmlのhiddenタグ
     */
    public static function generateHiddenTag($params, $excludes = array())
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        $hidden_tags = array();
        $keys = array();
        foreach ($params as $key => $value)
        {
            if (!in_array($key, $excludes))
            {
                self::getHiddenTag($key, $value, $keys, $hidden_tags);
            }
        }
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        return implode("\n", $hidden_tags);
    }

    /**
     * generateHiddenTagメソッドから呼び出される補助的なメソッド<br>
     * hiddenタグの実際の生成を行う<br>
     * パラメータが配列で渡されたときは再帰的に自身を呼び出す
     *
     * @param string $key
     *            パラメータのキー、hiddenタグのnameとなる
     * @param array $value
     *            パラメータの値、パラメータのキーが配列だった場合は配列のインデックスも入る
     * @param
     *            array &$keys パラメータのキーを格納する配列
     * @param
     *            array &$hidden_tags hiddenタグ
     * @return void
     */
    public static function getHiddenTag($key, $value, &$keys, &$hidden_tags)
    {
        if (is_array($value))
        {
            array_push($keys, $key);
            foreach ($value as $_key => $_value)
            {
                self::getHiddenTag($_key, $_value, $keys, $hidden_tags);
            }
            array_pop($keys);
        }
        else
        {
            $name = self::generateHiddenName($keys, $key);
            $hidden_tags[] = sprintf('<input type="hidden" name="%s" value="%s" />', $name, self::encodeValue($value));
        }
    }

    /**
     * getHiddenTagメソッドから呼び出される補助的なメソッド<br>
     * パラメータが配列で渡されたときでもhiddenタグのnameを動的に生成する
     *
     * @param array $keys
     *            パラメータのキーを格納する配列
     * @param string $key
     *            パラメータのキー、hiddenタグのnameとなる
     * @return string $name　hiddenタグのname
     */
    private static function generateHiddenName($keys, $key)
    {
        $name = '';
        $tmp = array();
        $tmp = $keys;
        $tmp[] = $key;
        foreach ($tmp as $n => $key)
        {
            if ($n == 0)
            {
                $name = $key;
                continue;
            }
            $name .= '[' . $key . ']';
        }
        return $name;
    }

    /**
     * URLエンコード<br>
     * 参考ページ ⇒ {@link http://dev-apamanshop/sample/inquiry/entry 問い合わせフォーム} (確認画面のhiddenタグで使用)
     *
     * @param string $value
     *            URLエンコードしたい文字列
     * @return string URLエンコードされた文字列
     */
    public static function encodeValue($value)
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        if (is_array($value))
        {
            foreach ($value as $k => $v)
            {
                $value[$k] = self::encodeValue($v);
            }
        }
        else
        {
            $value = urlencode($value);
        }
        __log_debug(__FILE__, __LINE__, __METHOD__, $value);
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        return $value;
    }

    /**
     * URLデコード<br>
     * 参考ページ ⇒ {@link http://dev-apamanshop/sample/inquiry/entry 問い合わせフォーム}
     * （確認画面の「前画面へ戻る」ボタンで遷移した時、フォームのデフォルト値で使用）
     *
     * @param string $value
     *            URLデコードしたい文字列
     * @return string URLデコードされた文字列
     */
    public static function decodeValue($value)
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        if (is_array($value))
        {
            foreach ($value as $k => $v)
            {
                $value[$k] = self::decodeValue($v);
            }
        }
        else
        {
            $value = urldecode($value);
        }
        __log_debug(__FILE__, __LINE__, __METHOD__, $value);
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        return $value;
    }

    /**
     * 文字コードの変換<br>
     *
     * @param mixed $target
     *            変換したい文字列
     * @param string $toEncoding
     *            変換する文字コード
     * @param string $fromEncoding
     *            元の文字コード
     * @return mixed 指定された文字コードに変換されたmixed
     */
    public static function mbConvertEncodingArray($target, $toEncoding, $fromEncoding = null)
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        if (is_array($target))
        {
            foreach ($target as $key => $value)
            {
                $target[$key] = self::mbConvertEncodingArray($value, $toEncoding, $fromEncoding);
            }
        }
        else
        {
            if (is_null($fromEncoding))
            {
                // 2015/02/17 $valueでは意味がないため、$targetに変更
                // $fromEncoding = mb_detect_encoding($value);
                $fromEncoding = mb_detect_encoding($target);
            }

            // 2015/02/17 文字コードが違う場合のみ変換
            // $target = mb_convert_encoding($target, $toEncoding, $fromEncoding);
            if ($toEncoding != $fromEncoding)
            {
                $target = mb_convert_encoding($target, $toEncoding, $fromEncoding);
            }
        }
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        return $target;
    }

    /**
     * パラメータの文字コードがUTF-8かをチェックし、真ならSJISに変換するメソッド<br>
     *
     * @param mixed $params
     * @return mixed $params
     */
    public static function convertUtf8ToSjis($params)
    {
        // __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        if (is_array($params))
        {
            foreach ($params as $key => $value)
            {
                $params[$key] = self::convertUtf8ToSjis($value);
            }
        }
        elseif (mb_detect_encoding($params, "UTF-8", TRUE))
        {
            $params = self::mbConvertEncodingArray($params, "SJIS", "UTF-8");
        }
        // __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');

        return $params;
    }

    /**
     *
     * CMSへ通常のHTTMLを表示するためのもの<br>
     *
     * @return なし(ただしHeaderに"x-pass-through:true"が追加される)
     */
    public static function outputXPassThroutgh()
    {
        header("x-pass-through:true");
    }

    /**
     * リダイレクト<br>
     * 参考ページ ⇒ {@link http://dev-apamanshop/sample/inquiry/entry 問い合わせフォーム} (確認画面→完了画面)
     *
     * @param string $url
     *            リダイレクト先のアドレス
     * @param array $params
     *            オプション
     * @return void
     * @todo オプションの定義
     */
    public static function redirect($url, $params = array(), $meta_redirect = true)
    {
        $cur_url = $_SERVER['REQUEST_URI'];
        if (!empty($params))
        {
            $url .= '?' . self::generateUrlParams($params);
        }
        if ($meta_redirect)
        {
            Apm_Util::outputXPassThroutgh();
            echo '<META http-equiv="refresh" CONTENT="0;URL=' . $url . '">';
        }
        else
        {
            header('Location: ' . $url);
        }
        exit();
    }

    private static function generateUrlParams($params)
    {
        $paramList = array();
        foreach ($params as $key => $value)
        {
            if (is_array($value))
            {
                foreach ($value as $v)
                {
                    $fromEncoding = mb_detect_encoding($v);
                    if ($fromEncoding != 'UTF-8')
                    {
                        $v = urlencode(mb_convert_encoding($v, 'UTF-8', $fromEncoding));
                    }

                    $paramList[] = $key . '[]=' . $v;
                }
            }
            else
            {
                $fromEncoding = mb_detect_encoding($value);
                if ($fromEncoding != 'UTF-8')
                {
                    $value = urlencode(mb_convert_encoding($value, 'UTF-8', $fromEncoding));
                }

                $paramList[] = $key . '=' . $value;
            }
        }
        return join('&', $paramList);
    }

    /**
     * XMLデータを出力<br>
     *
     * @param array $data
     *            URLエンコードしたい文字列
     * @param string $root
     * @return void
     */
    public static function outputXmlData($data)
    {
        // self::outputXmlHttpHeader();
        echo self::generateXml($data);
    }

    /**
     * CMS連携用のデータを出力<br>
     *
     * @param string $html
     *            アプリ側処理領域のhtml
     * @param
     *            array property プロパティデータ(タイトル ディスクリプション キーワード メタタグ パンくず アンカーリンク)
     * @return void
     */
    public static function outputCMSData($html, $property = array())
    {
        echo self::cmsApi($html, $property);
    }

    /**
     * CMS連携用のデータを出力<br>
     * 404ヘッダー版<br>
     *
     * @param string $html
     *            アプリ側処理領域のhtml
     * @param
     *            array property プロパティデータ(タイトル ディスクリプション キーワード メタタグ パンくず アンカーリンク)
     * @return void
     */
    public static function outputCMSData404($html, $property = array())
    {
        echo $property['meta'] . "\n";
        // echo $property['breadCrumb'] . "\n";
        echo $html;
    }

    /**
     * XMLデータを生成<br>
     *
     * @param array $data
     *            変換元データ
     * @param string $root
     * @return XML形式に成形された文字列
     */
    public static function generateXml($data)
    {
        require_once (APPLICATION_PATH . '/../library/Xml/XML_Serializer-0.20.2/XML/Serializer.php');
        $serializer = new XML_Serializer();
        $options = array(
            XML_SERIALIZER_OPTION_INDENT => "\t",
            XML_SERIALIZER_OPTION_XML_ENCODING => 'shift_jis',
            XML_SERIALIZER_OPTION_XML_DECL_ENABLED => TRUE,
            XML_SERIALIZER_OPTION_ROOT_NAME => 'xml',
            XML_SERIALIZER_OPTION_DEFAULT_TAG => 'item'
        );

        $serializer->serialize($data, $options);
        $result = $serializer->getSerializedData();

        return $result;
    }

    /**
     * CMS連携用のデータを生成<br />
     *
     * @param string $html
     *            アプリ側処理領域のhtml
     * @param array $property
     *            プロパティデータ(タイトル ディスクリプション キーワード メタタグ パンくず アンカーリンク)
     * @return string CMS連携用のXML形式に成形された文字列
     */
    public static function cmsApi($html, $property = array())
    {
        $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><contents></contents>');
        $text = $xml->addChild("title");
        self::addCDATA($property['title'], $text);
        $text = $xml->addChild("description");
        self::addCDATA($property['description'], $text);
        $text = $xml->addChild("keywords");
        self::addCDATA($property['keywords'], $text);
        $text = $xml->addChild("meta");
        self::addCDATA($property['meta'], $text);
        $text = $xml->addChild("breadCrumb");
        self::addCDATA($property['breadCrumb'], $text);
        $text = $xml->addChild("body");
        self::addCDATA($html, $text);
        $text = $xml->addChild("anchorLink");
        self::addCDATA($property['anchorLink'], $text);
        $getXML = $xml->asXML();
        $stXML = str_replace("UTF-8", "Shift_JIS", $getXML);
        return $stXML;
    }

    /**
     * 　* 出力するXMLにCDATAを挿入する<br />
     * 　*
     *
     * @param string $cdata_text
     * @param string $xml
     * @return
     *
     */
    public static function addCDATA($cdata_text, $xml)
    {
        $node = dom_import_simplexml($xml);
        $no = $node->ownerDocument;
        $node->appendChild($no->createCDATASection($cdata_text));
    }

    /**
     * データをUTF-8に変換してJSON形式で出力を行う<br />
     *
     * @param
     *            array 出力元データ
     * @return
     *
     */
    public static function outputJsonData_SJIStoUTF8($data)
    {
        $data = self::mbConvertEncodingArray($data, Apm_Config_Common::AJAX_CHAR_SET, 'SJIS');
        echo json_encode($data);
    }

    /**
     * データをUTF-8に変換してJSON形式で出力を行う<br />
     *
     * @param
     *            array 出力元データ
     * @return
     *
     */
    public static function outputJsonData_ToAjaxCharSet($data)
    {
        // 文字コードがUTF-8でない場合に実施
        $encode = mb_detect_encoding($data);
        if ($encode != Apm_Config_Common::AJAX_CHAR_SET)
        {
            $data = self::mbConvertEncodingArray($data, Apm_Config_Common::AJAX_CHAR_SET, $encode);
        }
        echo json_encode($data);
    }

    /**
     * 全国公開物件件数の取得<br />
     *
     * @return string 全国公開物件件数
     */
    public static function getZenkokuCount()
    {
        $sql = "";
        $sql .= "SELECT";
        $sql .= "    A03_ZENKOKU_CNT ";
        $sql .= "FROM";
        $sql .= "    A03AREA_BUKKEN_COUNT";
        $result = self::dbGetData($sql, "");

        return $result['A03_ZENKOKU_CNT'];
    }

    /**
     * すべての公開物ショップ数の取得<br />
     *
     * @return string すべての公開ショップ件数
     */
    public static function getAllShopCount()
    {
        $sql = "";
        $sql .= "SELECT";
        $sql .= "    COUNT(DISTINCT A06_TENPO_CD) AS A06_ZENKOKU_CNT ";
        $sql .= "FROM";
        $sql .= "    A06TENPO_BUKKEN_COUNT";

        $result = self::dbGetData($sql, "");

        return $result['A06_ZENKOKU_CNT'];
    }

    /**
     * すべての公開物件件数の取得<br />
     *
     * @return string すべての公開物件件数
     */
    public static function getAllBukkenCount()
    {
        $sql = "";
        $sql .= "SELECT";
        $sql .= "    * ";
        $sql .= "FROM";
        $sql .= "    A03AREA_BUKKEN_COUNT";

        $result = self::dbGetData($sql, "");

        return $result;
    }

    /**
     * 全国公開支援住宅物件件数の取得<br />
     *
     * @return string 全国公開支援住宅物件件数
     */
    public static function getSienjutakuCount()
    {
        $sql = "";
        $sql .= "SELECT";
        $sql .= "    A11_ZENKOKU_CNT ";
        $sql .= "FROM";
        $sql .= "    A11SIEN_JUTAKU_COUNT";
        $result = self::dbGetData($sql, "");

        return $result['A11_ZENKOKU_CNT'];
    }

    /**
     * httpヘッダーにxmlで必要な情報を埋め込む<br>
     *
     * @return void
     * @deprecated
     *
     */
    public static function outputXmlHttpHeader()
    {
        header("Cache-Control: no-cache, must-revalidate");
        header("Content-Type: text/xml; charset=Shift_JIS");
    }

    /**
     * httpヘッダーにxmlで必要な情報を埋め込む<br>
     * 404ヘッダー版<br>
     *
     * @return void
     * @deprecated
     *
     */
    public static function outputXmlHttpHeader404()
    {
        header("HTTP/1.1 404 Not Found");
        header("Cache-Control: no-cache, must-revalidate");
        header("Content-Type: text/xml; charset=Shift_JIS");
    }

    /**
     * LoginXML出力
     *
     * @return String ログインの成否
     * @return String ユーザのニックネーム
     * @return String(xml)
     */
    public static function outputLoginXML($login, $name)
    {
        echo self::generateLoginXML($login, $name);
    }

    /**
     * LoginXML生成
     *
     * @return String ログインの成否
     * @return String ユーザのニックネーム
     * @return String(xml)
     */
    public static function generateLoginXML($login = 'false', $name = '')
    {
        $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><auth></auth>');
        $text = $xml->addChild("status", $login);
        $text = $xml->addChild("name");
        self::addCDATA($name, $text);
        $getXML = $xml->asXML();
        $stXML = str_replace("UTF-8", "Shift_JIS", $getXML);
        return $stXML;
    }

    /**
     * module controller名取得
     *
     * @return String
     */
    public static function getModuleControllerName()
    {
        if (__is_cmsapi())
        {
            $module = __get_cmsapi_module();
            $controller = __get_cmsapi_controller();
        }
        else
        {
            $router = new Zend_Controller_Router_Rewrite();
            $req = $router->route(new Zend_Controller_Request_Http());
            $module = $req->getModuleName();
            $controller = $req->getControllerName();
        }

        $mcName = array(
            $module,
            $controller
        );

        return $mcName;
    }

    /**
     * パラメータで指定された画像を出力
     *
     * @param string $path
     *            画像のパス
     * @param string $extension
     *            画像の拡張子
     * @return void
     */
    public static function outputImage($path, $extension)
    {
        // 下記実行前にPHP Warning等が出力されていると画像は表示されない
        header('Content-type: image/' . $extension);
        self::outputXPassThroutgh();
        $fp = @fopen($path, 'rb');
        if ($fp)
        {
            $image = '';
            while (!feof($fp))
            {
                $image .= fread($fp, 8192);
            }
            echo $image;
            fclose($fp);
        }
        return;
    }

    /**
     * 機種依存文字を文字コードへ変換
     *
     * @param string $str
     *            変換対象文字列
     * @return string
     */
    public static function replaceUnicode($str)
    {
        // 文字コードがPHP文字コード(定数)でない場合に実施
        $encode = mb_detect_encoding($str);
        if ($encode == Apm_Config_Common::PHP_CHAR_SET)
        {
            return $str;
        }

        $arr = array(
            '㈱' => '&#12849;',
            '㎡' => '&#13217;',
            '㎞' => '&#13214;',
            '①' => '&#9312;',
            '②' => '&#9313;',
            '③' => '&#9314;',
            '④' => '&#9315;',
            '⑤' => '&#9316;',
            '⑥' => '&#9317;',
            '⑦' => '&#9318;',
            '⑧' => '&#9319;',
            '⑨' => '&#9320;',
            '⑩' => '&#9321;',
            '⑪' => '&#9322;',
            '⑫' => '&#9323;',
            '⑬' => '&#9324;',
            '⑭' => '&#9325;',
            '⑮' => '&#9326;',
            '⑯' => '&#9327;',
            '⑰' => '&#9328;',
            '⑱' => '&#9329;',
            '⑲' => '&#9330;',
            '⑳' => '&#9331;',
            'Ⅰ' => '&#8544;',
            'Ⅱ' => '&#8545;',
            'Ⅲ' => '&#8546;',
            'Ⅳ' => '&#8547;',
            'Ⅴ' => '&#8548;',
            'Ⅵ' => '&#8549;',
            'Ⅶ' => '&#8550;',
            'Ⅷ' => '&#8551;',
            chr(0x87) . chr(0x5c) => "&#8552;",
            "Ⅹ" => "&#8553;",
            '㍉' => '&#13129;',
            '㌔' => '&#13076;',
            '㌢' => '&#13090;',
            '㍍' => '&#13133;',
            '㌘' => '&#13080;',
            '㌧' => '&#13095;',
            '㌃' => '&#13059;',
            '㌶' => '&#13110;',
            '㍑' => '&#13137;',
            '㍗' => '&#13143;',
            '㌍' => '&#13069;',
            '㌦' => '&#13094;',
            '㌣' => '&#13091;',
            '㌫' => '&#13099;',
            '㍊' => '&#13069;',
            '㌻' => '&#13115;',
            '㎜' => '&#13212;',
            '㎝' => '&#13213;',
            '㎎' => '&#13198;',
            '㎏' => '&#13199;',
            '㏄' => '&#13252;',
            '㍻' => '&#13179;',
            '〝' => '&#12317;',
            '〟' => '&#12319;',
            '№' => '&#8470;',
            '㏍' => '&#13261;',
            '℡' => '&#8481;',
            '㊤' => '&#12964;',
            '㊥' => '&#12965;',
            '㊦' => '&#12966;',
            '㊧' => '&#12967;',
            '㊨' => '&#12968;',
            'ｫ2' => '&#12971;',
            '㈲' => '&#12850;',
            '㈹' => '&#12857;',
            '㍾' => '&#13182;',
            '㍽' => '&#13181;',
            '㍼' => '&#13180;',
            '≒' => '&#8786;',
            '≡' => '&#8801;',
            '∫' => '&#8747;',
            '∮' => '&#8750;',
            '∑' => '&#8721;',
            '√' => '&#8730;',
            '⊥' => '&#8869;',
            '∠' => '&#8736;',
            '∟' => '&#8735;',
            '⊿' => '&#8895;',
            '∵' => '&#8757;',
            '∩' => '&#8745;',
            '∪' => '&#8746;',
            'ⅰ' => '&#8560;',
            'ⅱ' => '&#8561;',
            'ⅲ' => '&#8562;',
            'ⅳ' => '&#8563;',
            'ⅴ' => '&#8564;',
            'ⅵ' => '&#8565;',
            'ⅶ' => '&#8566;',
            'ⅷ' => '&#8567;',
            'ⅸ' => '&#8568;',
            'ⅹ' => '&#8569;',
            '￢' => '&#65506;',
            '￤' => '&#65508;',
            '＇' => '&#65287;',
            '＂' => '&#65282;'
        );
        // return str_replace( array_keys($arr), array_values($arr), $str);

        return self::mb_str_replace(array_keys($arr), array_values($arr), $str);
    }

    /**
     * HTMLタグ文字を特殊文字へ変換
     *
     * @param string $str
     *            変換対象文字列
     * @return string
     */
    public static function replaceHtmlEntity($str)
    {
        $arr = array(
            // '&' => '&amp;',
            '"' => '&quot;',
            '<' => '&lt;',
            '>' => '&gt;',
            ' ' => '&nbsp;'
        );

        return self::mb_str_replace(array_keys($arr), array_values($arr), $str);
    }

    public static function removePlaceFolder($str)
    {
        $arr = array(
            '${campaign}' => '',
            '${accessInfo}' => ''
        );
        return str_replace(array_keys($arr), array_values($arr), $str);
    }

    /**
     * マルチバイト対応 str_replace
     *
     * @param array $search
     *            検索文字列
     * @param array $replace
     *            置換文字列
     * @param string $subject
     *            対象文字列
     *
     * @return string
     */
    public static function mb_str_replace($search, $replace, $subject)
    {
        foreach ($search as $key => $value)
        {
            $subject = mb_ereg_replace($value, $replace[$key], $subject);
        }

        return $subject;
    }

    public static function mb_str_replace2($search, $replace, $subject, $encoding = null)
    {
        $tmp = mb_regex_encoding();
        mb_regex_encoding(func_num_args() > 3 ? $encoding : mb_internal_encoding());
        foreach ((array) $search as $i => $s)
        {
            if (!is_array($replace))
            {
                $r = $replace;
            }
            elseif (isset($replace[$i]))
            {
                $r = $replace[$i];
            }
            else
            {
                $r = '';
            }
            $s = mb_ereg_replace('[.\\\\+*?\\[^$(){}|]', '\\\\0', $s);
            $subject = mb_ereg_replace($s, $r, $subject);
        }
        mb_regex_encoding($tmp);
        return $subject;
    }

    public static function mb_explode($delimiter, $string, $limit = -1, $encoding = null)
    {
        $tmp = mb_regex_encoding();
        mb_regex_encoding(func_num_args() > 3 ? $encoding : mb_internal_encoding());
        $delimiter = mb_ereg_replace('[.\\\\+*?\\[^$(){}|]', '\\\\0', $delimiter);
        $ret = mb_split($delimiter, $string, $limit);
        mb_regex_encoding($tmp);
        return $ret;
    }

}
?>
